package com.zerui.manager.icc.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dahuatech.hutool.http.Method;
import com.dahuatech.icc.exception.ClientException;
import com.zerui.manager.icc.dto.*;
import com.zerui.manager.icc.properties.ICCProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.*;

/**
 * 门禁服务
 */
@Slf4j
@Service("iccAccessControlService")
public class AccessControlInfoService extends AbstractBase {

	@Resource
	private ICCProperties iccProperties;

	/**
	 * 批量授权
	 *
	 * @param personCodes  人员编号
	 * @param channelCodes 通道编号
	 * @param
	 * @return
	 */
	public Boolean batchAuthority(List<String> personCodes, List<String> channelCodes, String startDate, String endDate) throws ClientException {
		Assert.notNull(personCodes, "人员编号不能为空");
		Assert.notNull(channelCodes, "通道编号不能为空");
		BatchAuthorityVO authorityVO = new BatchAuthorityVO();
		authorityVO.setPersonCodes(personCodes);
		authorityVO.setStartDate(startDate);
		authorityVO.setEndDate(endDate);
		authorityVO.setTimeQuantumId(1l);
		List<PrivilegeDetailVO> privilegeDetailVOS = new ArrayList<>();
		for (String channelCode : channelCodes) {
			PrivilegeDetailVO pdv = new PrivilegeDetailVO();
			pdv.setPrivilegeType(PrivilegeTypeEnum.CHANNEL.getCode());
			pdv.setResourceCode(channelCode);
			pdv.setTimeQuantumId("1");
			privilegeDetailVOS.add(pdv);
		}
		authorityVO.setPrivilegeDetails(privilegeDetailVOS);
		this.generalRequest(this.iccProperties.getAccessControl().getBatchAuthorityUrl(), Method.POST, authorityVO, null);
		return true;
	}

	/**
	 * 批量删除指定人员编号的授权
	 * PS : 批量删除人员的所有权限，删除的权限包括：卡、指纹、人像
	 *
	 * @param personCodes 人员编号
	 * @return
	 * @throws ClientException
	 */
	public Boolean batchDelete(String... personCodes) throws ClientException {
		Assert.notNull(personCodes, "人员编号不能为空");
		JSONObject jo = new JSONObject();
		jo.put("personCodes", Arrays.asList(personCodes));
		this.generalRequest(this.iccProperties.getAccessControl().getBatchDeleteUrl(), Method.POST, jo, null);
		return true;
	}

	/**
	 * 删除单个人员权限
	 *
	 * @param personCode 人员编号
	 * @return
	 * @throws ClientException
	 */
	public Boolean singleDelete(String personCode, List<String> channelCodes) throws ClientException {
		Assert.notNull(personCode, "人员编号不能为空");
		Assert.notNull(channelCodes, "门禁通道不能为空");
		JSONObject jo = new JSONObject();
		jo.put("personCode", personCode);
		// 删除人员授权 和 门组授权
		JSONArray jrr = new JSONArray();
		for (String channelCode : channelCodes) {
			JSONObject item1 = new JSONObject();
			item1.put("privilegeType", PrivilegeTypeEnum.CHANNEL.getCode()); // 通道
			item1.put("resourceCode", channelCode); // 通道
			jrr.add(item1);
			JSONObject item2 = new JSONObject();
			item2.put("privilegeType", PrivilegeTypeEnum.DOOR_GROUP.getCode()); // 通道
			item2.put("resourceCode", channelCode); // 通道
			jrr.add(item2);
		}
		jo.put("deleteDetails", jrr);
		this.generalRequest(this.iccProperties.getAccessControl().getSingleDeleteUrl(), Method.POST, jo, null);
		return true;
	}

	/**
	 * 查询指定人员编号的授权信息
	 *
	 * @param personCode 人员编号
	 * @return
	 */
	public PersonAuthorityVO selectByCode(String personCode) throws ClientException {
		Assert.notNull(personCode, "人员编号不能为空");
		Map<String, String> joParam = new HashMap<>();
		joParam.put("personCode", personCode);
		JSONObject dataJo = this.generalRequest(this.renderUrl(this.iccProperties.getAccessControl().getPersonAuthorityUrl(), joParam), Method.POST, joParam, "data");
		log.info("来自ICC的人员授权信息 => {}", dataJo.toJSONString());
		List<PersonAuthorityVO> personAuthorityVOS = this.convert2TypeData(dataJo, PersonAuthorityVO.class);
		return !personAuthorityVOS.isEmpty() ? personAuthorityVOS.get(0) : null;
	}

	/**
	 * 开门
	 *
	 * @param channelCodes 门禁通道编码
	 */
	public void openDoor(String... channelCodes) throws ClientException {
		Assert.notNull(channelCodes, "门禁通道编码不能为空");
		JSONObject joBody = new JSONObject();
		joBody.put("channelCodeList", Arrays.asList(channelCodes));
		this.generalRequest(this.iccProperties.getAccessControl().getRemoteOpenDoorUrl(), Method.POST, joBody, null);
	}

	/**
	 * 关门
	 *
	 * @param channelCodes 门禁通道编码
	 */
	public void closeDoor(String... channelCodes) throws ClientException {
		Assert.notNull(channelCodes, "门禁通道编码不能为空");
		JSONObject joBody = new JSONObject();
		joBody.put("channelCodeList", Arrays.asList(channelCodes));
		this.generalRequest(this.iccProperties.getAccessControl().getRemoteCloseDoorUrl(), Method.POST, joBody, null);
	}

	/**
	 * 设置常开
	 *
	 * @param channelCodes 门禁通道编码
	 */
	public void stayOpen(String... channelCodes) throws ClientException {
		Assert.notNull(channelCodes, "门禁通道编码不能为空");
		JSONObject joBody = new JSONObject();
		joBody.put("channelCodeList", Arrays.asList(channelCodes));
		this.generalRequest(this.iccProperties.getAccessControl().getRemoteStayOpenUrl(), Method.POST, joBody, null);
	}

	/**
	 * 设置常闭
	 *
	 * @param channelCodes 门禁通道编码
	 */
	public void stayClose(String... channelCodes) throws ClientException {
		Assert.notNull(channelCodes, "门禁通道编码不能为空");
		JSONObject joBody = new JSONObject();
		joBody.put("channelCodeList", Arrays.asList(channelCodes));
		this.generalRequest(this.iccProperties.getAccessControl().getRemoteStayCloseUrl(), Method.POST, joBody, null);
	}

	/**
	 * 设置普通模式
	 *
	 * @param channelCodes 门禁通道编码
	 */
	public void stayNormal(String... channelCodes) throws ClientException {
		Assert.notNull(channelCodes, "门禁通道编码不能为空");
		JSONObject joBody = new JSONObject();
		joBody.put("channelCodeList", Arrays.asList(channelCodes));
		this.generalRequest(this.iccProperties.getAccessControl().getRemoteStayNormalUrl(), Method.POST, joBody, null);
	}

	/**
	 * 订阅门禁报警类型
	 *
	 * @param subscribeVO 订阅信息
	 */
	public void subscribeAlarmEvents(SubscribeVO subscribeVO) throws ClientException {
		Assert.notNull(subscribeVO, "订阅信息不能为空");
		JSONObject joBody = new JSONObject();
		joBody.put("param", subscribeVO);
		this.generalRequest(this.iccProperties.getAccessControl().getSubscribeAccessUrl(), Method.POST, joBody, null);
	}

	/**
	 * 取消订阅指定名称的事件
	 *
	 * @param name 事件名称
	 */
	public void cancelSubscribe(final String name) throws ClientException {
		Assert.notNull(name, "订阅事件名不能为空");
		Map<String, String> joParam = new HashMap<>();
		joParam.put("name", name);
		this.generalRequest(this.renderUrl(this.iccProperties.getAccessControl().getCancelSubAccessUrl(), joParam), Method.DELETE, null, null);
	}

	/**
	 * 展示所有事件订阅列表
	 *
	 * @return
	 */
	public JSONObject listSubscribe() throws ClientException {
		JSONObject joBody = new JSONObject();
		JSONObject joData = this.generalRequest(this.iccProperties.getAccessControl().getListSubAccessUrl(), Method.GET, null, "data");
		return joData.getJSONObject("subscribeMap");
	}

}
